﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using XNAGuiLib.GuiLibFrames;
using XNAGuiLib.GuiLibButtons;
using XNAGuiLib.GuiLibResourceManager;
using XNAGuiLib.GuiLibAction;

namespace XNAGuiLib.GuiLibPanel
{
    public class PanelObject : InterfaceObject
    {
        #region Private Field - InterfaceObjects
        private new List<InterfaceObject> InterfaceObjects
        {
            get;
            set;
        }
        #endregion


        #region Field - VisiblePage
        protected int _visiblePage = 1;
        /// <summary>
        /// gets or sets the page number which is the default/current visible one
        /// </summary>
        public int VisiblePage
        {
            get
            {
                return _visiblePage;
            }
            set
            {
                if (value < _ios.Count)
                {
                    _visiblePage = value;
                }
                else _visiblePage = _ios.Count;

                for (int i = 1; i < _ios.Count; i++)
                {
                    _ios[i].Visible = false;
                }
                _ios[_visiblePage].Visible = true;
            }
        }
        #endregion

        #region Field - BarThickness
        protected int _barThickness;
        /// <summary>
        /// 
        /// </summary>
        public int BarThickness
        {
            get
            {
                return _barThickness;
            }
            set
            {
                _barThickness = value;

                SetupRectangles(_barThickness);
            }
        }
        #endregion
        
        public GuiResourceManager.ResourceManagerType ResourceType;

        protected new Rectangle _bounds;
        protected Rectangle _barRectangle;
        protected Rectangle _contentRectangle;

        protected Orientation _barOrientation = Orientation.Top;

        #region Field - BarActive
        protected bool _barActive = true;
        /// <summary>
        /// gets if the bar area is active
        /// </summary>
        public bool BarActive
        {
            get
            {
                return _barActive;
            }
        }
        #endregion

        #region Field - Bar
        protected FrameObject _bar;
        /// <summary>
        /// gets or sets the InterfaceObject in the bar area
        /// </summary>
        protected FrameObject Bar
        {
            get
            {
                return _bar;
            }
            set
            {
                try
                {
                    _bar = value;
                    _bar.Parent = this;
                    _bar.RelativePosition = new Vector2(_barRectangle.X, _barRectangle.Y);
                    _bar.Rescale(new Vector2(_barRectangle.Width, _barRectangle.Height));

                    if (!_ios.Contains(_bar))
                        _ios.Insert(0, _bar);
                    else
                    {
                        _ios.Remove(_bar);
                        _ios.Insert(0, _bar);
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.StackTrace);
                }
            }
        }
        #endregion

        TextObject _toTitle;
        ButtonObject _btLeft;
        ButtonObject _btRight;

        #region Enumeration - Orientation
        public enum Orientation
        {
            Bottom,
            Top,
            Left,
            Right
        }
        #endregion


        #region Constructor - PanelObject(Game game, string name, Rectangle bounds, BarOrientation barOrientation, int barThickness, bool visible)
        public PanelObject(Game game, string name, Rectangle bounds, Orientation barOrientation, int barThickness, bool visible)
            : base(game, name, new Vector2(bounds.X, bounds.Y), visible)
        {
            _bounds = bounds;
            _barOrientation = barOrientation;
            _barThickness = barThickness;
            SetupRectangles(_barThickness);

            this.Font = GuiResourceManager.Instance(this.Game).FontManager.Load<SpriteFont>("DefaultFrame");

            _btLeft = new HorizonsButton(this.Game, "_prev", Statics.V2(5, 5), Statics.V2(20, 17), "<<", ButtonObject.ButtonObjectState.Unclicked, ButtonObject.ButtonSize.BS017x017);
            _btRight = new HorizonsButton(this.Game, "_next", Statics.V2(25, 5), Statics.V2(20, 17), ">>", ButtonObject.ButtonObjectState.Unclicked, ButtonObject.ButtonSize.BS017x017);
            _toTitle = new TextObject("", this.Font, "_title", Statics.V2(50, 6), Statics.V2(70, 13), true);
            _toTitle.TextColor = Color.White;
            FrameObject hfo = new HorizonsFrame(this.Game, "_bar", "", 0, 0, 100, 300, true);

            hfo.Add(_btLeft);
            hfo.Add(_btRight);
            hfo.Add(_toTitle);
            hfo.InstallInterface();
            this.Bar = hfo;

            _btLeft.InstallAction(ActionFactory.InterfaceObjectAction(this,
                                          _btLeft,
                                          Action.CommandType.Custom,
                                          MouseAction.Inputs.MouseButtonPressed,
                                          MouseAction.MouseButtons.Left,
                                          "prevPage",
                                          Action.KeyModifiers.None));

            _btRight.InstallAction(ActionFactory.InterfaceObjectAction(this,
                                          _btRight,
                                          Action.CommandType.Custom,
                                          MouseAction.Inputs.MouseButtonPressed,
                                          MouseAction.MouseButtons.Left,
                                          "nextPage",
                                          Action.KeyModifiers.None));

            this._initialized = true;
        }
        #endregion

        #region Method - Page(int page, InterfaceObject io, ButtonObject tab)
        /// <summary>
        /// gets or sets the InterfaceObject in the content area
        /// </summary>
        public InterfaceObject Page(int page, InterfaceObject io, string title)
        {
            io.Title = title;
            io.Parent = this;
            io.RelativePosition = new Vector2(_contentRectangle.X, _contentRectangle.Y);
            io.Rescale(new Vector2(_contentRectangle.Width, _contentRectangle.Height));

            if (!_ios.Contains(io))
            {
                if (_ios.Count > page)
                    _ios.Insert(page, io);
                else
                    _ios.Add(io);
            }
            else if (_ios.Count > page)
            {
                _ios.Remove(io);
                _ios.Insert(page, io);
            }

            VisiblePage = page;
            _toTitle.Text = _ios[_visiblePage].Title;
            return _ios[page];
        }
        #endregion

        #region Method - SetTitle(int page, string title)
        public void SetTitle(int page, string title)
        {
            if (_ios.Count > page && page > 0)
            {
                _ios[page].Title = title;
                _toTitle.Text = _ios[_visiblePage].Title;
            }
        }
        #endregion


        #region Protected Method - #endregion()
        protected void NextPage()
        {
            if (this._ios.Count > _visiblePage + 1)
            {
                ExecuteCommand("showPage" + (_visiblePage + 1));
                _visiblePage++;
                _toTitle.Text = _ios[_visiblePage].Title;
            }
        }
        #endregion

        #region Protected Method - PreviousPage()
        protected void PreviousPage()
        {
            if (_visiblePage - 1 > 0)
            {
                ExecuteCommand("showPage" + (_visiblePage - 1));
                _visiblePage--;
                _toTitle.Text = _ios[_visiblePage].Title;
            }
        }
        #endregion

        #region Protected Method - ShowPage(string command)
        protected void ShowPage(string command)
        {
            int index = -1;
            try
            {
                index = int.Parse(command.Replace("showPage", ""));

                if (index >= 1)
                {
                    for (int i = 1; i < _ios.Count; i++)
                    {
                        _ios[i].Visible = false;
                    }

                    Console.WriteLine("showPage: " + index + " named " + this._ios[index].Name);
                    this._ios[index].Visible = true;
                }
            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex.StackTrace);
            }
        }
        #endregion


        #region Private Method - SetupRectangles(int barThickness)
        private void SetupRectangles(int barThickness)
        {
            switch (_barOrientation)
            {
                case Orientation.Top:
                    _contentRectangle = new Rectangle(_bounds.X, _bounds.Y + barThickness, _bounds.Width, _bounds.Height - barThickness);
                    _barRectangle = new Rectangle(_bounds.X, _bounds.Y, _bounds.Width, barThickness);
                    break;

                case Orientation.Bottom:
                    _contentRectangle = new Rectangle(_bounds.X, _bounds.Y, _bounds.Width, _bounds.Height - barThickness);
                    _barRectangle = new Rectangle(_bounds.X, _bounds.Y + _bounds.Height - barThickness, _bounds.Width, barThickness);
                    break;

                case Orientation.Left:
                    _contentRectangle = new Rectangle(_bounds.X, _bounds.Y + barThickness, _bounds.Width, _bounds.Height - barThickness);
                    _barRectangle = new Rectangle(_bounds.X, _bounds.Y, _bounds.Width, barThickness);
                    // _contentRectangle = new Rectangle(_bounds.X + barThickness, _bounds.Y, _bounds.Width - barThickness, _bounds.Height);
                    // _barRectangle = new Rectangle(_bounds.X, _bounds.Y, barThickness, _bounds.Height);
                    break;

                case Orientation.Right:
                    _contentRectangle = new Rectangle(_bounds.X, _bounds.Y, _bounds.Width, _bounds.Height - barThickness);
                    _barRectangle = new Rectangle(_bounds.X, _bounds.Y + _bounds.Height - barThickness, _bounds.Width, barThickness);
                    // _contentRectangle = new Rectangle(_bounds.X, _bounds.Y, _bounds.Width - barThickness, _bounds.Height);
                    // _barRectangle = new Rectangle(_bounds.X + _bounds.Width - barThickness, _bounds.Y, barThickness, _bounds.Height);
                    break;
            }
        }
        #endregion

        #region Override Method - ExecuteCommand(string command)
        public override void ExecuteCommand(string command)
        {
            if (command.StartsWith("showPage"))
            {
                ShowPage(command);
            }
            else if (command.StartsWith("nextPage"))
            {
                NextPage();
            }
            else if (command.StartsWith("prevPage"))
            {
                PreviousPage();
            }
        }
        #endregion
    }
}